<template>
  <div class="pdf-merge-wrapper">
    <!-- 左侧：目录面板 -->
    <aside class="toc-panel" v-if="settings.showToc">
      <h3>目录</h3>
      <ol>
        <li
            v-for="(item, idx) in tableOfContents"
            :key="idx"
            @click="goToPage(item.pageNumber)"
        >
          {{ item.title }}
        </li>
      </ol>
    </aside>

    <!-- 中间：PDF 渲染区域 -->
    <main class="pdf-viewer-panel">
      <div class="pdf-canvas-container">
        <canvas ref="pdfCanvasRef"></canvas>
      </div>
      <div class="pdf-toolbar">
        <button @click="prevPage">上一页</button>
        <span>{{ currentPage }} / {{ totalPages }}</span>
        <button @click="nextPage">下一页</button>
      </div>
    </main>

    <!-- 右侧：设置面板 -->
    <aside class="settings-panel">
      <h3>设置</h3>
      <div class="setting-item">
        <label>
          <input type="checkbox" v-model="settings.showCover" />
          显示封面
        </label>
      </div>
      <div class="setting-item">
        <label>
          <input type="checkbox" v-model="settings.showToc" />
          显示目录
        </label>
      </div>
      <div class="setting-item">
        <label>
          <input type="checkbox" v-model="settings.showWatermark" />
          显示水印
        </label>
      </div>
      <div class="setting-item">
        <label>
          <input type="checkbox" v-model="settings.showPageNumbers" />
          显示页码
        </label>
      </div>
      <!--
        如果你希望在用户切换这些选项后，PDF 立即重新合并并刷新，
        可以给这些复选框添加 watch，根据新选项重新调用 mergePDF 函数。
      -->
    </aside>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'

// 1) pdf-lib 用于合并/修改 PDF
import { PDFDocument } from 'pdf-lib'

// 2) pdfjs-dist 用于渲染 PDF
import * as pdfjsLib from 'pdfjs-dist'
// pdf.js 需要指定 worker
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker?url'
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker

// ------------------- 数据源示例 ---------------------
// 假设需要合并的 PDF 链接及其标题（可作为目录名）
interface PdfItem {
  title: string
  url: string
}
const pdfItems: PdfItem[] = [
  { title: '第一章：Vue 介绍', url: '/assets/pdf/vue-intro.pdf' },
  { title: '第二章：TypeScript 基础', url: '/assets/pdf/ts-basic.pdf' },
  { title: '第三章：Vue 3 + TS 项目示例', url: '/assets/pdf/vue3-ts-example.pdf' },
]

// 目录项
interface TocItem {
  title: string
  pageNumber: number // 在合并后 PDF 中的起始页（或你想跳转的页面）
}
const tableOfContents = ref<TocItem[]>([])

// ------------------- 设置项（右侧面板） ---------------------
const settings = reactive({
  showCover: true,       // 是否添加封面
  showToc: true,         // 是否显示左侧目录
  showWatermark: false,  // 是否添加水印（示例只在封面加文字，更多水印可遍历每页）
  showPageNumbers: true, // 是否显示页码（此示例只在UI层面显示，若要在PDF中添加需要pdf-lib再写）
})

// ------------------- PDF.js 渲染相关 ---------------------
// PDF.js 加载后的 PDFDocumentProxy
let pdfDocProxy: any = null

// 当前页、总页数
const currentPage = ref(1)
const totalPages = ref(0)

// 画布引用
const pdfCanvasRef = ref<HTMLCanvasElement | null>(null)

// ------------------- 生命周期：组件挂载后 ---------------------
onMounted(async () => {
  // 1. 合并 PDF
  const mergedPdfBytes = await mergePDF()
  if (!mergedPdfBytes) return

  // 2. 用 PDF.js 加载合并后的 PDF
  const loadingTask = pdfjsLib.getDocument({ data: mergedPdfBytes })
  pdfDocProxy = await loadingTask.promise
  totalPages.value = pdfDocProxy.numPages

  // 3. 默认渲染第 1 页
  renderPage(currentPage.value)
})

// ------------------- 合并 PDF 的核心函数 ---------------------
async function mergePDF(): Promise<Uint8Array | null> {
  try {
    // 创建一个新的 PDFDocument（空白）
    const mergedDoc = await PDFDocument.create()

    // 如果需要添加封面页
    if (settings.showCover) {
      const coverPage = mergedDoc.addPage()
      coverPage.drawText('这是自动生成的封面', {
        x: 50,
        y: 700,
        size: 24,
      })


    }

    let currentPageIndex = settings.showCover ? 1 : 0

    // 清空目录（重新生成）
    tableOfContents.value = []

    for (const item of pdfItems) {
      // 读取每个 PDF
      const arrayBuffer = await fetch(item.url).then((res) => res.arrayBuffer())
      const pdfDoc = await PDFDocument.load(arrayBuffer)

      // 拷贝所有页面
      const copiedPages = await mergedDoc.copyPages(pdfDoc, pdfDoc.getPageIndices())
      copiedPages.forEach((page) => mergedDoc.addPage(page))

      // 添加到目录（记录该章节在合并后 PDF 中的起始页）
      tableOfContents.value.push({
        title: item.title,
        pageNumber: currentPageIndex + 1, // 跳转到这一章第一页
      })

      // 更新当前 PDF 累计页数
      currentPageIndex += copiedPages.length
    }

    // 导出最终合并后的 PDF 二进制数据
    const mergedPdfBytes = await mergedDoc.save()
    return mergedPdfBytes
  } catch (error) {
    console.error('合并 PDF 出错：', error)
    return null
  }
}

// ------------------- 用 PDF.js 渲染某一页 ---------------------
async function renderPage(pageNum: number) {
  if (!pdfDocProxy || !pdfCanvasRef.value) return

  // 获取指定页
  const page = await pdfDocProxy.getPage(pageNum)
  const scale = 1.0
  const viewport = page.getViewport({ scale })

  // 设置 canvas 大小
  const canvas = pdfCanvasRef.value
  const context = canvas.getContext('2d')
  canvas.height = viewport.height
  canvas.width = viewport.width

  // 渲染该页
  const renderContext = {
    canvasContext: context,
    viewport,
  }
  page.render(renderContext)
}

// ------------------- 翻页逻辑 ---------------------
function prevPage() {
  if (currentPage.value > 1) {
    currentPage.value--
    renderPage(currentPage.value)
  }
}
function nextPage() {
  if (currentPage.value < totalPages.value) {
    currentPage.value++
    renderPage(currentPage.value)
  }
}

// ------------------- 点击目录跳转 ---------------------
function goToPage(pageNum: number) {
  if (pageNum >= 1 && pageNum <= totalPages.value) {
    currentPage.value = pageNum
    renderPage(currentPage.value)
  }
}
</script>

<style scoped>
.pdf-merge-wrapper {
  display: flex;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}

/* 左侧目录面板 */
.toc-panel {
  width: 220px;
  border-right: 1px solid #ccc;
  padding: 16px;
  box-sizing: border-box;
}
.toc-panel h3 {
  margin-top: 0;
}
.toc-panel ol {
  padding-left: 20px;
  cursor: pointer;
}
.toc-panel li {
  margin: 8px 0;
  color: #333;
}

/* 中间 PDF 显示区 */
.pdf-viewer-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 16px;
  box-sizing: border-box;
}
.pdf-canvas-container {
  width: 100%;
  display: flex;
  justify-content: center;
  overflow: auto;
}
.pdf-toolbar {
  margin-top: 16px;
  display: flex;
  gap: 8px;
  align-items: center;
}

/* 右侧设置面板 */
.settings-panel {
  width: 220px;
  border-left: 1px solid #ccc;
  padding: 16px;
  box-sizing: border-box;
}
.settings-panel h3 {
  margin-top: 0;
}
.setting-item {
  margin-bottom: 8px;
}
</style>
